import { Inter } from 'next/font/google'
import { useState, useRef, useCallback, useEffect, useMemo } from 'react'
import { useRouter } from 'next/router'
import Image from 'next/image'
import Head from 'next/head'
import {
  Textarea,
  Input,
  Select,
  SelectItem,
  Button,
  Tooltip,
  Modal,
  ModalContent,
  ModalBody,
} from '@nextui-org/react'
import Title from '@/components/Title'
import Hero from '@/components/Hero'
import Steps from '@/components/Steps'
import Intro from '@/components/Intro'
import Entries from '@/components/Entries'
import FAQ from '@/components/FAQ'
import Output from '@/components/Output'

import { useGlobalContext } from '@/contexts'
import initAssistantRequest from '@/shared/assistantRequest'
import { getPageData, getCreateParams, getSelectOptions } from '@/shared/utils'
import { AssistantProps } from '~/src/services'

import iconMagic from '@/assets/icons/ic_magic.png'
import runoutPC from '@/assets/runout-pc.png'
import runoutMobile from '@/assets/runout-mobile.png'

const inter = Inter({ subsets: ['latin'] })

const Generator = () => {
  const router = useRouter()
  const { pathname } = router
  const { insData } = useGlobalContext()
  const [keywords, setKeywords] = useState('')
  const [desc, setDesc] = useState('')
  const [locale, setLocale] = useState('')

  const [modalOpen, setModalOpen] = useState(false)
  const [isLoading, setIsLoading] = useState(false)
  const [errorTips, setErrorTips] = useState('')
  const [errorTipsOpen, setErrorTipsOpen] = useState(false)
  const [replyData, setReplyData] = useState('')
  const [historyList, setHistoryList] = useState<
    { timestamp: number; value: string }[]
  >([])

  const abortController = useRef<AbortController>()
  const textRef = useRef('')
  const timestampRef = useRef(0)

  const pageData = useMemo(
    () => getPageData(pathname, insData) as AssistantProps,
    [pathname, insData]
  )

  const lngs = useMemo(() => {
    const code = 'Language'
    return getSelectOptions(pageData, code)
  }, [pageData])

  useEffect(() => {
    if (!locale && lngs?.length) {
      setLocale(lngs[0].value)
    }
  }, [lngs?.length, locale])

  useEffect(() => {
    setTimeout(() => setErrorTipsOpen(false), 1000 * 5)
  }, [errorTips])

  const handleMessagesStream = useCallback((stream: string) => {
    if (!stream) return

    if (!textRef.current) {
      timestampRef.current = new Date().getTime()
    }

    textRef.current += stream.replace(/(\n|-=- --)/g, ' ')
    textRef.current = textRef.current.replace(/(\n|-=-n--)/g, '<br/>')

    setReplyData(textRef.current)
  }, [])

  const errorHandler = useCallback((type: string, failedType: string) => {
    // trackAssistant('error', { status: type, failedType })
    setErrorTips(failedType)
    setErrorTipsOpen(true)
  }, [])

  const handleOpenError = useCallback(
    (status: string) => {
      setIsLoading(false)

      const maps: { [key: string]: () => void } = {
        '202': () => {
          errorHandler('202', 'validate failed')
        },
        '241': () => {
          // credit run out
          // errorHandler('241', 'credit run out')
          setModalOpen(true)
        },
        '277': () => {
          errorHandler('277', 'request too much')
        },
        '278': () => {
          errorHandler('278', 'request frequency has reached the upper limit')
        },
        '279': () => errorHandler('279', 'forbidden words'),
        '280': () => {
          errorHandler(
            '280',
            'The input context exceeds 2000 characters, please cut it down and try again.'
          )
        },
        '401': () => {
          // free credit run out
          // errorHandler('401', 'free credit run out')
          setModalOpen(true)
        },
        '403': () => {
          // forbidden words
          errorHandler(
            '403',
            'There is a risk of violations, which may be due to factors such as violations and pornography'
          )
        },
        '429': () => {
          errorHandler('429', 'request frequency has reached the upper limit')
        },
      }
      if (maps[status]) {
        maps[status]()
        return
      } else {
        errorHandler(`${status}`, 'Server Error')
      }
    },
    [errorHandler]
  )

  const handleResetAnswerState = () => {
    textRef.current = ''
    timestampRef.current = 0
  }

  const handleMessageEnd = () => {
    setReplyData('')
    setHistoryList((prev) => [
      { timestamp: timestampRef.current, value: textRef.current },
      ...prev,
    ])
  }

  const handleGenerate = () => {
    if (!pageData) return
    const { assistantRequest, abortController: controller } =
      initAssistantRequest()

    abortController.current = controller

    setIsLoading(true)

    const createPrams = getCreateParams(pageData, [keywords, desc, locale])

    assistantRequest({
      data: createPrams,
      language: 'en',
      onOpenSuccess(response: any) {
        console.log('onOpenSuccess event >>>', response)
        handleResetAnswerState()
        if (response.status !== 200) {
          handleOpenError(response.status)
        }
      },
      onOpenError: (response: any) => {
        console.log('onOpenError event >>>', response)
        handleOpenError(response.status)
      },
      onMessage: (event: any) => {
        handleMessagesStream(event?.data)
      },
      onMessageEnd: () => {
        console.log('onMessageEnd event >>>')
        handleMessageEnd()
        // handleMessageStreamEnd()
      },
      onClose: () => {
        console.log('onClose event >>>')
        setIsLoading(false)
      },
      onError: (event: any) => {
        console.log('onError event >>>', event)
        setIsLoading(false)
      },
    }).catch((err) => {
      console.log('assistantRequest err >>>>', err)
    })
  }

  return (
    <>
      <div className="flex flex-col gap-y-4 w-[840px] min-h-[316px] px-3.5 py-6 bg-white mx-[auto] mb-row shadow-lg max-sm:w-full max-sm:mb-0 rounded-[20px]">
        <div className="flex flex-col gap-y-2">
          <div className="flex flex-row items-center justify-between">
            <span className="text-base font-bold">Generate by keywords *</span>
            <span className="text-sm text-secondary">
              {keywords.length}/200
            </span>
          </div>
          <Textarea
            variant="bordered"
            placeholder="Example: fashion, food, pet, ootd, art "
            value={keywords}
            onValueChange={(val) => {
              setKeywords(val.slice(0, 200))
            }}
          />
        </div>
        <div className="flex flex-row justify-between gap-x-8 max-sm:flex-col max-sm:gap-y-4">
          <div className="flex-1 flex flex-col gap-y-2">
            <div className="flex flex-row items-center justify-between">
              <span className="text-base font-bold">Description</span>
              <span className="text-sm text-secondary">{desc.length}/100</span>
            </div>
            <Input
              variant="bordered"
              placeholder="A short description here"
              value={desc}
              onValueChange={(val) => {
                setDesc(val.slice(0, 100))
              }}
            />
          </div>
          <div className="flex-1 flex flex-col gap-y-2">
            <div className="flex flex-row items-center justify-between">
              <span className="text-base font-bold">Language</span>
            </div>
            {lngs && (
              <Select
                aria-label="select language"
                variant="bordered"
                selectionMode="single"
                items={lngs}
                selectedKeys={[locale]}
                defaultSelectedKeys={[locale]}
                onSelectionChange={(val: any) => {
                  setLocale(val.currentKey)
                }}
              >
                {lngs.map((lng) => (
                  <SelectItem key={lng.value} value={lng.value}>
                    {lng.label}
                  </SelectItem>
                ))}
              </Select>
            )}
          </div>
        </div>
        <Tooltip
          color={'danger'}
          isOpen={errorTipsOpen}
          showArrow
          isDismissable
          placement="bottom"
          content={errorTips}
        >
          <Button
            className="flex w-full button-primary cursor-pointer"
            isDisabled={!keywords.length || isLoading}
            isLoading={isLoading}
            onClick={handleGenerate}
          >
            <Image src={iconMagic} alt="icon" width={22} height={22} />
            Generate
          </Button>
        </Tooltip>
        <div className="flex flex-col gap-4 max-sm:hidden">
          {[
            { timestamp: timestampRef.current, value: replyData },
            ...historyList,
          ].map((item, index) => (
            <Output
              key={`${item.timestamp}-${index}`}
              timeStamp={new Date().getTime()}
              content={item.value}
              // onCopy={() => {}}
              onDelete={() => setHistoryList((prev) => prev.splice(index, 1))}
            />
          ))}
        </div>
      </div>
      <div className="flex flex-col gap-6 pt-6 lg:hidden">
        {[
          { timestamp: timestampRef.current, value: replyData },
          ...historyList,
        ].map((item, index) => (
          <Output
            key={`${item.timestamp}-${index}`}
            timeStamp={new Date().getTime()}
            content={item.value}
            // onCopy={() => {}}
            onDelete={() => setHistoryList((prev) => prev.splice(index, 1))}
          />
        ))}
      </div>
      <Modal
        isOpen={modalOpen}
        placement="center"
        onClose={() => setModalOpen(false)}
      >
        <ModalContent>
          <ModalBody className="p-0">
            <Image
              className="max-sm:hidden"
              src={runoutPC}
              alt="run out picture"
              width={819}
              height={662}
            ></Image>
            <Image
              className="sm:hidden"
              src={runoutMobile}
              alt="run out picture"
              width={640}
              height={872}
            ></Image>
          </ModalBody>
        </ModalContent>
      </Modal>
    </>
  )
}

export default function Home() {
  const HeroData = {
    title: 'Quickly Find Top Hashtags on Instagram with AI',
    desc: [
      `Everyone knows that hashtags are key to social media success. However, finding 20-30 high-quality hashtags for each Instagram post can consume a lot of valuable time and effort. That's why we bring you this free Instagram hashtag generator. Simply enter relevant keywords or descriptions, and this AI-powered hashtag generator will give you a list of popular and trending hashtags tailored to your target audience, helping to increase the reach and engagement of your Instagram posts. `,
      `Remember, the Instagram hashtag generator is completely free and can offer great ideas to help your posts get more reach. It's definitely worth trying out and bookmarking.`,
    ],
    img: require('@/assets/hashtag/hero.png').default,
  }
  const StepsData = {
    title: 'Best Practice for Using AI Hashtag Generator',
    steps: [
      {
        step: 'Step 1',
        title: 'Add keywords and description',
        desc: `To use the Instagram tag generator, simply enter keywords related to your post. You can also add a brief description to help the AI understand what your post is about. Press the 'Generate' button, and within seconds, you will see 10 of the best Instagram hashtags for your post or story.`,
        img: require('@/assets/hashtag/step-1.png').default,
      },
      {
        step: 'Step 2',
        title: 'Generate more niche hashtags',
        desc: `As you know,  it's best to use a mix of broad and niche hashtags, which will help you reach a wider audience. So, you can enter more specific words or synonyms related to your topic into the free hashtag generator tool, and it will generate more Instagram niche hashtags.`,
        img: require('@/assets/hashtag/step-2.png').default,
      },
      {
        step: 'Step 3',
        title: 'Use hashtags on Instagram',
        desc: `Choose the Instagram hashtag that best fits your needs and paste it at the end of your post. Remember, Instagram allows up to 30 hashtags per post, but for best results, it’s recommended to only use 3 to 5 hashtags per post, story, or reel.`,
        img: require('@/assets/hashtag/step-3.png').default,
      },
    ],
  }
  const IntroData = {
    title: 'Benefits of Using AI Instagram Hashtag Generator',
    desc: `Using hashtags is likely to increase the visibility of your Instagram posts. Your Instagram photos or videos are more likely to get better engagement (clicks, likes, and comments) if they appear on relevant hashtag pages. Our free Instagram hashtag generator will help you quickly and efficiently implement your hashtag strategy.`,
    intros: [
      {
        title: 'Increase Instagram Performance',
        desc: `The Instagram hashtag generator can quickly find hashtags that are highly relevant to your post, helping to attract more target audience, increase visits to your profile page, and boost user interactions.`,
        img: require('@/assets/hashtag/intro-1.png'),
      },
      {
        title: 'Save Time and Effort',
        desc: `Get rid of the hassle of searching for the best Instagram hashtags. With the help of AI, it can all be done in seconds. You can quickly find the hashtags that best fit your topic, rather than the most popular ones.`,
        img: require('@/assets/hashtag/intro-2.png'),
      },
      {
        title: 'Get New Hashtag Ideas',
        desc: `Reusing the same hashtags in the same order over and over may affect your Instagram account performance. Our Instagram hashtag maker offers an endless supply of unique hashtag combinations, ensuring your Instagram posts remain fresh and effective.`,
        img: require('@/assets/hashtag/intro-3.png'),
      },
    ],
  }
  const EntriesData = {
    title: 'Dicover More Instagram Generator Tools',
    entries: [
      {
        label: 'Instagram Caption Generator',
        link: '/instagram-caption-generator/',
      },
      { label: 'Instagram Bio Generator', link: '/instagram-bio-generator/' },
      {
        label: 'Instagram Username Generator',
        link: '/instagram-username-generator/',
      },
    ],
  }
  const FAQData = {
    title: 'FAQs using AI Hashtag Generator',
    faqs: [
      {
        question: 'How does Instagram hashtag generator work?',
        answer: `Our Instagram tag generator can generate the best hashtag suggestions based on your input. It combines data from popular Instagram hashtags, the number of posts, and search trends to help maximize the visibility and impressions of your posts.`,
      },
      {
        question: 'Is there a free hashtag generator for Instagram?',
        answer: `Generating Instagram hashtags with SSSgram is completely free; no registration or payment required. Our goal is to help you improve the performance of your Instagram account. However, due to the costs associated with AI computing power, we limit the number of times each user can use the AI Instagram Hashtag Generator per day.`,
      },
      {
        question: 'Can I use hashtag generator for Instagram reels?',
        answer: `Of course, our hashtag generator also works with Instagram Reels. Just like feed posts, hashtags work equally well when included in the title or comments on Reels. If used correctly, they can significantly increase your reach.`,
      },
      {
        question:
          'What is the difference between SSSgram and other hashtag generators?',
        answer: `Our Instagram hashtag generator doesn't simply create a hashtag from scratch. Instead, it selects the most effective hashtags for your posts based on their actual usage, reach, and relevance on Instagram. Additionally, we regularly update our AI database with trending Instagram tags to continually improve the tool’s accuracy and effectiveness.`,
      },
      {
        question: 'Does this hashtag generator work on TikTok and Facebook?',
        answer: `Yes, except to generate hashtags for Instagram, this tool can also be used as a creative hashtag generator for TikTok, Facebook, Pinterest, LinkedIn, Twitter, and more. Just provide your keywords and you'll receive relevant and popular hashtag suggestions within seconds.`,
      },
      {
        question: 'Is it better to use more or less hashtags on Instagram?',
        answer: `According to Instagram, you can use up to 30 tags on a post. However, it is rare to need so many hashtags. Instagram actually recommends using only three to five hashtags per post. Adding too many hashtags can negatively affect the platform’s algorithm.`,
      },
      {
        question: 'Do hashtags increase followers?',
        answer: `Instagram hashtags allow your posts to be discovered by a wider audience. Including relevant hashtags in the title or comments section of a post can increase its visibility. However, this is not guaranteed. To truly improve your Instagram performance, you must carefully choose the right hashtags and effectively optimize them for SEO.`,
      },
      {
        question: 'What is the most popular hashtag on Instagram right now?',
        answer: `"Here are the top 10 trending Instagram hashtags as of now:
      #love
      #instagood
      #photooftheday
      #fashion
      #beautiful
      #happy
      #cute
      #tbt
      #like4like
      #followme"`,
      },
    ],
  }
  return (
    <main
      className={`w-view min-h-screen mx-[auto] ${inter.className} max-sm:w-sView max-sm:px-[10px]`}
    >
      <Head>
        <title>AI Instagram Hashtag Generator Free Online - No Sign Up</title>
        <meta
          name="description"
          content="AI Instagram hashtag generator can help you quickly find top hashtags on Instagram, thereby increase your Instagram engagement and reach a larger audience. "
        />
        <meta
          property="og:title"
          content="AI Instagram Hashtag Generator Free Online - No Sign Up"
        />
        <meta
          property="og:description"
          content="AI Instagram hashtag generator can help you quickly find top hashtags on Instagram, thereby increase your Instagram engagement and reach a larger audience. "
        />
      </Head>
      <Title
        title="Free AI Instagram Hashtag Generator"
        desc="Boost reach, followers, and likes on Instagram with top hashtags on Instagram."
      ></Title>
      <Generator />
      <Hero {...HeroData} />
      <Steps {...StepsData} />
      <Intro {...IntroData} />
      <FAQ {...FAQData} />
      <Entries {...EntriesData} />
    </main>
  )
}
